#include "kernel/ilog.h"
#include "input/iinputsystem.h"
#include "inputsystemSDL.h"
#include "keyboarddeviceSDL.h"
#include "mousedeviceSDL.h"

namespace rengine3d {

	CInputSystemSDL::CInputSystemSDL(IRenderDriver* renderDriver): m_renderDriver(renderDriver) {
		m_mouseDevice		= NULL;
		m_keyboardDevice	= NULL;
		m_updatableName		= "CInputSystemSDL";
	}

	CInputSystemSDL::~CInputSystemSDL(){
		this->Shutdown();
	}

	string_t CInputSystemSDL::GetName(void) {
		return "CInputSystemSDL";
	}

	string_t CInputSystemSDL::GetDescription(void) {
		return "Input system SDL";
	}

	string_t CInputSystemSDL::GetVersion(void) {
		return "0.0.1";
	}

	bool CInputSystemSDL::Init(void){

		Log("Initializing InputSystemSDL...\n");

		//SDL_SetRelativeMouseMode(SDL_TRUE);

		m_mouseDevice = new CMouseDeviceSDL("CMouseDeviceSDL", m_renderDriver, this);
		if (!m_mouseDevice->Init())
			return false;

		m_keyboardDevice = new CKeyboardDeviceSDL("CKeyboardDeviceSDL", this);
		if (!m_keyboardDevice->Init())
			return false;

		return true;
	}

	void CInputSystemSDL::Shutdown(void){
		Log("Shutdown InputSystemSDL...\n");

		for ( actionMapIt_t  it = m_actionsMap.begin(); it != m_actionsMap.end(); ++it ) {
			SafeDelete(it->second);
		}

		m_actionsMap.clear();

		SafeDelete(m_mouseDevice);
		SafeDelete(m_keyboardDevice);
	}

	void CInputSystemSDL::OnUpdate(real timeStep){
		SDL_Event sdlEvent;

		while(SDL_PollEvent(&sdlEvent)!=0)	{
			m_events.push_back(sdlEvent);
			switch ( sdlEvent.type )
			{
			case SDL_QUIT:
				int a =0;
				break;
			};
		}

		m_keyboardDevice->Update();
		m_mouseDevice->Update();

		for ( actionMapIt_t  it = m_actionsMap.begin(); it != m_actionsMap.end(); ++it ) {
			it->second->Update(timeStep);
		}

		m_events.clear();
	}

	void CInputSystemSDL::AddAction(IInputAction* action){
		m_actionsMap.insert(actionMap_t::value_type(action->GetName(), action));	
	}

	IInputAction* CInputSystemSDL::GetAction(string_t name){
		actionMapIt_t it = m_actionsMap.find(name);
		if (it==m_actionsMap.end())
			return NULL;
		return it->second;
	}

	bool CInputSystemSDL::RemoveAction(string_t name){
		actionMapIt_t it = m_actionsMap.find(name);
		if (it==m_actionsMap.end())
			return false;

		IInputAction* action = it->second;
		SafeDelete(action);
		m_actionsMap.erase(name);

		return true;
	}

	bool CInputSystemSDL::CheckAction(const string_t name){
		IInputAction* action = GetAction(name);
		if (!action)
			return false;
		return action->IsPressed();
	}

	IKeyboardDevice* CInputSystemSDL::GetKeyboardDevice(void){
		return m_keyboardDevice;
	}

	IMouseDevice* CInputSystemSDL::GetMouseDevice(void){
		return m_mouseDevice;
	}

}